﻿using AutoMapper;
using MD5Hash;
using MediatR;
using RBAC.ErrorCode;
using RBAC.Interstructrue.Base;
using RBAC.Write.Api.Application.Command.User;
using System.Transactions;
using Microsoft.Extensions.Logging;
using RBAC.Domain.RBAC;

namespace RBAC.Write.Api.Application.Handler.User
{
    public class CreateUserHandler : IRequestHandler<CreateUserCommand, APIResult<int>>
    {
        private readonly IBaseRepository<UserModel> userRepository;
        private readonly ILogger<CreateUserHandler> logger;
        private readonly IMapper mapper;
        private readonly IBaseRepository<UserRoleModel> userRoleRepository;

        public CreateUserHandler(IBaseRepository<UserModel> userRepository, ILogger<CreateUserHandler> logger, IMapper mapper, IBaseRepository<UserRoleModel> userRoleRepository)
        {
            this.userRepository = userRepository;
            this.logger = logger;
            this.mapper = mapper;
            this.userRoleRepository = userRoleRepository;
        }
        
        /// <summary>
        /// 创建用户
        /// </summary>
        /// <param name="request"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public Task<APIResult<int>> Handle(CreateUserCommand request, CancellationToken cancellationToken)
        {
            APIResult<int> res = new APIResult<int>();
            
            try
            {
                logger.LogInformation("开始创建用户: {UserName}", request.UserName);
                
                // 1. 数据验证
                if (string.IsNullOrWhiteSpace(request.UserName))
                {
                    res.Code = APIEnums.Error;
                    res.Msg = "用户名不能为空";
                    logger.LogWarning("用户名验证失败: {UserName}", request.UserName);
                    return Task.FromResult(res);
                }
                
                if (string.IsNullOrWhiteSpace(request.Password))
                {
                    res.Code = APIEnums.Error;
                    res.Msg = "密码不能为空";
                    logger.LogWarning("密码验证失败: 用户 {UserName}", request.UserName);
                    return Task.FromResult(res);
                }
                
                // 2. 检查用户名是否已存在
                var existingUser = userRepository.GetFirstOrDefault("UserName = @UserName AND IsDeleted = false", new { UserName = request.UserName });
                if (existingUser != null)
                {
                    res.Code = APIEnums.Error;
                    res.Msg = "用户名已存在";
                    logger.LogWarning("用户名已存在: {UserName}", request.UserName);
                    return Task.FromResult(res);
                }
                
                var user = mapper.Map<UserModel>(request);
                user.Password = user.Password.GetMD5();
                user.CreateTime = DateTime.Now;
                user.IsDeleted = false;
                
                logger.LogInformation("用户映射完成: UserName={UserName}, CreateTime={CreateTime}", 
                    user.UserName, user.CreateTime);
                
                using (TransactionScope tran = new TransactionScope())
                {
                    try
                    {
                        // 3. 创建用户
                        var userId = userRepository.Create(user);
                        if (userId <= 0)
                        {
                            throw new InvalidOperationException("用户创建失败，返回的ID无效");
                        }
                        logger.LogInformation("用户创建成功，ID: {UserId}", userId);
                        
                        // 4. 批量创建用户角色关联（使用Dapper批量操作）
                        if (request.RoleId != null && request.RoleId.Any())
                        {
                            logger.LogInformation("开始批量创建用户角色关联，角色数量: {RoleCount}", request.RoleId.Count());
                            
                            // 准备批量插入的数据
                            var userRoles = request.RoleId.Select(roleId => new UserRoleModel
                            {
                                UserId = userId,
                                RoleId = roleId,
                                IsDeleted = false,
                                CreateTime = DateTime.Now
                            }).ToList();
                            
                            // 使用批量插入方法
                            var batchResult = userRoleRepository.CreateBatch(userRoles);
                            logger.LogInformation("用户角色关联批量创建完成: 预期 {ExpectedCount} 条，实际创建 {ActualCount} 条", 
                                userRoles.Count, batchResult);
                            
                            // 严格验证批量插入结果
                            if (batchResult != userRoles.Count)
                            {
                                throw new InvalidOperationException($"批量创建用户角色关联失败: 预期 {userRoles.Count} 条，实际创建 {batchResult} 条");
                            }
                        }
                        else
                        {
                            logger.LogInformation("没有指定角色ID，跳过用户角色关联创建");
                        }
                        
                        tran.Complete();
                        
                        res.Code = APIEnums.Success;
                        res.Data = userId;
                        res.Msg = "用户创建成功";
                        
                        logger.LogInformation("用户 {UserName} 创建完成，ID: {UserId}", request.UserName, userId);
                    }
                    catch (Exception ex)
                    {
                        logger.LogError(ex, "创建用户过程中发生错误: {Message}", ex.Message);
                        res.Code = APIEnums.Error;
                        res.Msg = "创建用户失败";
                        res.Data = 0;
                        throw;
                    }
                }
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "创建用户失败: {Message}", ex.Message);
                res.Code = APIEnums.Error;
                res.Msg = "创建用户失败";
                res.Data = 0;
            }
            
            return Task.FromResult(res);
        }
    }
}
